﻿/**
 * @class Ext.ux.PhotoFormPanel
 * @extends Ext.Panel
 *
 * Ext.ux.PhotoFormPanel description
 *
 * @author    Maple
 * @copyright (c) 2009, foyo
 * @date      20th. May 2009
 * @version   0.1
 * @revision  0.1
 *
 */
 
// create namespace
Ext.ns('foyo');
foyo.SITE_URL = '';

/**
 * Creates new Ext.ux.PhotoFormPanel
 * @constructor
 * @param {Object} config A config object
 */
Ext.ux.PhotoFormPanel = Ext.extend(Ext.FormPanel, {
	
    /**
     * @cfg {Number} width
     * The width of this component in pixels (defaults to 140).
     */
	width: 140
		
    /**
     * @cfg {Number} height
     * The height of this component in pixels (defaults to 250).
     */
	,height: 250
	
    /**
     * @cfg {Number} photoWidth
     * The height of this photo in pixels (defaults to 120).
     */
	,photoWidth: 120
		
    /**
     * @cfg {Number} photoHeight
     * The height of this photo in pixels (defaults to auto).
     */
	,photoHeight: 0
	
	/**
     * @cfg {String} url, essential param
     * The url where to post uploaded files.
     */
	,url: ''
		
    /**
     * @cfg {RegExp} filename regex
     * A JavaScript RegExp object to be tested against the file name during validation 
     */
	,regex: new RegExp('[\w\W]*\.[bmp|gif|jpg|png]')
		
    /**
     * @cfg {RegExp} regex
     * The error text to display if regex is used and the test fails during validation (defaults to "")
     */
	,regexText: 'Image formats limit to bmp, gif, jpg, png'
	
	/**
     * @cfg {Bool} readOnly
     * True to forbid user to upload photo (defaults to false).
     */
	,readOnly: false
		
	 /**
     * @cfg {String} photoUrl
     * The url of image shown (defaults to ''), access to the methods getPhotoUrl and setPhotoUrl.
     */
	,photoUrl: ''
		
	/**
     * @cfg {String} defaultPhotoUrl
     * The url of image shown when photoUrl equals to ''(defaults to '').
     */
	,defaultPhotoUrl: ''
	
    ,initComponent:function() {
 
        // hard coded config (it cannot be changed while instantiating)
        // {{{
        var config = {
        	items:this.createItems()
        	,buttons:this.createButtons()
        	,bodyStyle: 'padding: 0 5px 0 5px;'
        	,fileUpload: true
        	,height: this.height
        	,width: this.width
        }; // eo config object
 
        // apply config
        Ext.apply(this, Ext.apply(this.initialConfig, config));
        // }}}
 
        // call parent
        Ext.ux.PhotoFormPanel.superclass.initComponent.apply(this, arguments);
 
        // parent call post-processing, e.g. install event handlers
        this.addEvents(
            /**
             * @event photouploaded
             * Fire when the photo is uploaded successfully.
             * @param {Panel} this
             * @param {String} url
             */
            "photouploaded"
        );    
 
    } // eo function initComponent

    ,onRender:function() {
     
        // parent call pre-processing
 
        // call parent
        Ext.ux.PhotoFormPanel.superclass.onRender.apply(this, arguments);
 
        // parent call post-processing, e.g. install event handlers on rendered components
        this.fufPhoto = this.items.get(1);
        this.fufPhoto.on('fileselected', this.onFufPhotoFileSelected, this);
 
    } // eo function onRender
    
    ,htmlRule: '<img src="{0}" width="{1}px" {2} style="vertical-align:middle;" />'
    
    // private
    ,createItems: function(){
    	var items = [];
    	var h = this.photoHeight?String.format('height="{1}px"', this.photoHeight):'';
    	var u = this.photoUrl || this.defaultPhotoUrl;
    	var height = this.height - 70;
    	items.push({
    		xtype: 'panel'
    		,height: height
    		,html: u ? String.format(this.htmlRule, u, this.photoWidth, h) : ''
    		,bodyStyle: String.format('vertical-align:middle;text-align:center;padding: 10px {0}px 10px {0}px;height:{1}px;line-height:{1}px;', (this.width-this.photoWidth-10)/2, height)
    		,border: false
    	});
    	items.push({
            xtype: 'fileuploadfield',
            anchor: '97.5%',
            emptyText: '',
            hideLabel: true,
            name: 'photo',
            hidden: this.readOnly,
            buttonCfg: {
                text: '',
                iconCls: 'fis-icon-upload'
            }
        });
    	return items;
    }
    
    // private
    ,createButtons: function(){
    	var btns = [];
    	this.btnSubmit = new Ext.Button({
    		text: 'Upload'
    		,handler: this.onBtnSubmitClick.createDelegate(this)
    		,disabled: true
    		,hidden: this.readOnly
    	});
    	btns.push(this.btnSubmit);
    	return btns;
    }
    
    // private
    ,onBtnSubmitClick: function(){
    	var fn = this.fufPhoto.getValue();
    	if(!fn){
    		Ext.MessageBox.alert('Warning', 'Please select a file first!');
    		return;
    	}
		if (this.validateFile()){
	    	this.form.submit({
	    		url: this.url
	    		,method: 'POST'
	    		,waitMsg: 'Uploading your photo...'
	    		,success: this.onFormSubmitSuccess
				,scope: this
	    	});
	    	this.btnSubmit.disable();
    	}
    }
    
    // private
    ,onFormSubmitSuccess: function(form, action){
    	var r = Ext.decode(action.response.responseText);
    	if (r.success){
	    	this.photoUrl = r.data[0].url;
	    	var h = this.photoHeight?String.format('height="{1}px"', this.photoHeight):'';
	    	var html = this.photoUrl ? String.format(this.htmlRule, this.photoUrl, this.photoWidth, h):'';
	    	this.items.get(0).body.update(html);
    		this.fireEvent("photouploaded", this, this.photoUrl);
    	}
    }
    
    // private
    ,onFufPhotoFileSelected: function(field, value){
    	if (this.validateFile()){
    		this.btnSubmit.enable();
    	}
    }
    
    // private
    ,validateFile: function(){
    	var fn = this.fufPhoto.getValue();
    	var flag = true;
    	if(!fn)
    		flag = false;
    	var idx = -1;
    	if ((idx=fn.lastIndexOf('.')) == -1 || idx == fn.length-1 )
    		flag = false;
    	var fx = fn.substr(idx+1);
    	if (!new RegExp('bmp|png|gif|jpg').test(fx))
    		flag = false;
    	if (!flag){
    		Ext.MessageBox.alert('Warning', this.regexText);
    		this.btnSubmit.disable();
    	}
    	return flag;
    }
    
    /**
     * Get photo url.
     * @return {String} The photo url
     */
    ,getPhotoUrl: function(){
    	return this.photoUrl;
    }
    
    /**
     * Set photo url.
     * @param {String} photo url
     */
    ,setPhotoUrl: function(url){
    	this.photoUrl = url;
    	var h = this.photoHeight?String.format('height="{1}px"', this.photoHeight):'';
    	var html = this.photoUrl ? String.format(this.htmlRule, this.photoUrl, this.photoWidth, h):'';
    	this.items.get(0).body.update(html);
    }
    
    /**
     * Set whether the photo can be changed by user.
     * @param {Bool} readonly, defautlt to true
     */
    ,setReadOnly: function(readOnly){
    	readOnly = (readOnly === true ? true: false);
    	this.fufPhoto.setVisible(!readOnly);
    	this.btnSubmit.setVisible(!readOnly);
    	this.readOnly = readOnly;
    }
}); // eo extend
 
// register xtype
Ext.reg('photoformpanel', Ext.ux.PhotoFormPanel); 
// eof